﻿namespace CatClient.Message.Spi.Heartbeat.Extend
{
    using CatClient.Message.Spi.Heartbeat.Extend.Netstat;
    using CatClient.Util;
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Runtime.CompilerServices;

    internal class ConnectionInfo : HeartbeatExtention, IDisposable
    {
        private readonly Stopwatch _stopwatch = new Stopwatch();
        private readonly Dictionary<string, double> _dic;
        private readonly NetstatManager _netstat;

        public ConnectionInfo()
        {
            this._stopwatch.Start();
            this._dic = new Dictionary<string, double>();
            this._netstat = new NetstatManager();
            this._stopwatch.Stop();
            LogInfoWriter.GetInstance("Cat", 0, LogInfoWriter.LogLayout.Default).Info($"Heartbeat {"ConnectionInfo"} init finish. {this._stopwatch.ElapsedMilliseconds}ms");
        }

        public void Dispose()
        {
        }

        public override void Refresh()
        {
            this._stopwatch.Restart();
            int processId = Process.GetCurrentProcess().Id;
            List<TcpProcessRecord> list1 = (from c in this._netstat.GetAllTcpConnections()
                where c.ProcessId == processId
                select c).ToList<TcpProcessRecord>();
            List<TcpProcessRecord> list = (from c in list1
                where c.State == MibTcpState.ESTABLISHED
                select c).ToList<TcpProcessRecord>();
            IEnumerable<IGrouping<ushort, TcpProcessRecord>> enumerable = from c in list group c by c.LocalPort;
            List<ushort> values = (from c in list1
                where c.State == MibTcpState.LISTENING
                select c.LocalPort).Distinct<ushort>().ToList<ushort>();
            this._dic.Clear();
            this._dic.Add("TcpConnections", (double) list.Count);
            this._dic.Add("ListenPorts", (double) values.Count);
            //base.AdditionInfo = "Listening Ports: [" + string.Join<ushort>(",", values) + "]";
            //base.AdditionInfo = base.AdditionInfo + "Connections: [" + string.Join(",", (IEnumerable<string>) (from g in enumerable select $"{g.Key}@{g.Count<TcpProcessRecord>()}")) + "]";
            this._stopwatch.Stop();
            LogInfoWriter.GetInstance("Cat", 0, LogInfoWriter.LogLayout.Default).Info($"Heartbeat {"ConnectionInfo"} refresh finish. {this._stopwatch.ElapsedMilliseconds}ms");
        }

        public override Dictionary<string, double> Dict =>
            this._dic;

        public override string Id =>
            "Connection";

        //[Serializable, CompilerGenerated]
        //private sealed class <>c
        //{
        //    public static readonly ConnectionInfo.<>c <>9 = new ConnectionInfo.<>c();
        //    public static Func<TcpProcessRecord, bool> <>9__8_1;
        //    public static Func<TcpProcessRecord, ushort> <>9__8_2;
        //    public static Func<TcpProcessRecord, bool> <>9__8_3;
        //    public static Func<TcpProcessRecord, ushort> <>9__8_4;
        //    public static Func<IGrouping<ushort, TcpProcessRecord>, string> <>9__8_5;

        //    internal bool <Refresh>b__8_1(TcpProcessRecord c) => 
        //        (c.State == MibTcpState.ESTABLISHED);

        //    internal ushort <Refresh>b__8_2(TcpProcessRecord c) => 
        //        c.LocalPort;

        //    internal bool <Refresh>b__8_3(TcpProcessRecord c) => 
        //        (c.State == MibTcpState.LISTENING);

        //    internal ushort <Refresh>b__8_4(TcpProcessRecord c) => 
        //        c.LocalPort;

        //    internal string <Refresh>b__8_5(IGrouping<ushort, TcpProcessRecord> g) => 
        //        $"{g.Key}@{g.Count<TcpProcessRecord>()}";
        //}
    }
}

